package com.ittest.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.yaml.snakeyaml.util.UriEncoder;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 对http get以及post请求进行封装
 */
public class HttpClientUtils {
    public static CookieStore cookieStore;
    // 修正：声明为CloseableHttpClient（支持关闭）
    public static CloseableHttpClient httpclient;

    static {
        cookieStore = new BasicCookieStore();
        // 新增：配置超时参数（避免线程阻塞）
        org.apache.http.client.config.RequestConfig requestConfig = org.apache.http.client.config.RequestConfig.custom()
                .setConnectTimeout(5000)    // 连接超时：5秒（三次握手超时）
                .setConnectionRequestTimeout(5000) // 从连接池获取连接超时：5秒
                .setSocketTimeout(10000)    // 读取响应超时：10秒（数据传输超时）
                .build();

        // 初始化HttpClient时添加超时配置
        httpclient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    // 新增：提供关闭HttpClient的方法（程序退出时调用，释放连接池）
    public static void closeHttpClient() throws IOException {
        if (httpclient != null) {
            httpclient.close();
        }
    }


    //Get请求不带参数
//    public static JSONObject executeGet(String url){
//
//        try {
//            //创建httpGet对象
//            HttpGet httpGet = new HttpGet(url);
//            return doRequest(httpGet);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    };
    // 示例：Get请求不带参数（添加URL校验）
    public static JSONObject executeGet(String url){
        // 校验URL非空
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            HttpGet httpGet = new HttpGet(url);
            return doRequest(httpGet);
        } catch (Exception e) {
            throw new RuntimeException("GET请求（无参数）执行失败", e);
        }
    };




    //Get请求带参数
//    public static JSONObject executeGet(String url, Map<String,String> parmatersMap){
//
//        try {
//            //创建uribuilder对象
//            URIBuilder uriBuilder = new URIBuilder();
//            //获取参数所有key的集合
//            Set<String> keySet = parmatersMap.keySet();
//            for (String key : keySet) {
//                uriBuilder.addParameter(key,parmatersMap.get(key));
//            }
//            //添加完之后
//            URI uri = uriBuilder.build();
//            //创建httpGet对象
//            HttpGet httpGet = new HttpGet(url);
//            return doRequest(httpGet);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    };

    // 修复：Get请求带参数
    public static JSONObject executeGet(String url, Map<String,String> parmatersMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            // 关键：基于原始URL创建URIBuilder，而非空构造器
            URIBuilder uriBuilder = new URIBuilder(url);
            if (parmatersMap != null && !parmatersMap.isEmpty()) {
                Set<String> keySet = parmatersMap.keySet();
                for (String key : keySet) {
                    uriBuilder.addParameter(key, parmatersMap.get(key));
                }
            }
            // 构建包含参数的完整URI
            URI uri = uriBuilder.build();
            // 使用构建后的URI创建HttpGet（而非原url）
            HttpGet httpGet = new HttpGet(uri);
            return doRequest(httpGet);
        } catch (Exception e) {
            throw new RuntimeException("GET请求（带参数）执行失败", e);
        }
    };




    //Get请求带参数带请求头
//    public static JSONObject executeGet(String url, Map<String,String> parmatersMap,Map<String,String> headersMap){
//
//        try {
//            //创建uribuilder对象
//            URIBuilder uriBuilder = new URIBuilder();
//            if (parmatersMap != null){
//            //获取参数所有key的集合
//            Set<String> keySet = parmatersMap.keySet();
//            for (String key : keySet) {
//                uriBuilder.addParameter(key,parmatersMap.get(key));
//            }
//            //添加完之后
//            URI uri = uriBuilder.build();
//        }
//            //创建httpGet对象
//            HttpGet httpGet = new HttpGet(url);
//            //添加请求头
//
//            if (headersMap != null){
//                //获取参数所有key的集合
//                Set<String> headerSet = headersMap.keySet();
//                for (String key : headerSet) {
//                    httpGet.addHeader(key,headersMap.get(key));
//            }
//        }
//            return doRequest(httpGet);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    };
    // 修复：Get请求带参数带请求头
    public static JSONObject executeGet(String url, Map<String,String> parmatersMap, Map<String,String> headersMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            // 基于原始URL初始化URIBuilder
            URIBuilder uriBuilder = new URIBuilder(url);
            if (parmatersMap != null && !parmatersMap.isEmpty()) {
                Set<String> keySet = parmatersMap.keySet();
                for (String key : keySet) {
                    uriBuilder.addParameter(key, parmatersMap.get(key));
                }
            }
            // 构建完整URI
            URI uri = uriBuilder.build();
            // 使用正确的URI创建HttpGet
            HttpGet httpGet = new HttpGet(uri);
            // 添加请求头
            if (headersMap != null && !headersMap.isEmpty()) {
                Set<String> headerSet = headersMap.keySet();
                for (String key : headerSet) {
                    httpGet.addHeader(key, headersMap.get(key));
                }
            }
            return doRequest(httpGet);
        } catch (Exception e) {
            throw new RuntimeException("GET请求（带参数+请求头）执行失败", e);
        }
    };

    //Post请求不带参数
//    public static JSONObject executePost(String url){
//        try {
//            HttpPost httpPost = new HttpPost(url);
//            doRequest(httpPost);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return null;
//    }
//
    // 修复：Post请求不带参数
    public static JSONObject executePost(String url){
        try {
            HttpPost httpPost = new HttpPost(url);
            // 接收doRequest的返回值并返回（原代码未返回）
            return doRequest(httpPost);
        } catch (Exception e) {
            // 统一抛异常（原代码仅printStackTrace，调用方无法感知错误）
            throw new RuntimeException("POST请求（无参数）执行失败", e);
        }
    }



    //Post请求带普通参数
//    public static JSONObject executePost(String url, Map<String,String> parmatersMap){
//
//        try {
//            HttpPost httpPost = new HttpPost(url);
//            if (parmatersMap != null && parmatersMap.size()>0){
//                List<BasicNameValuePair> list = new ArrayList<>();
//                //键值对关系
//                Set<Map.Entry<String, String>> entries = parmatersMap.entrySet();
//                for (Map.Entry<String, String> entry : entries) {
//                    list.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
//                }
//                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list);
//                httpPost.setEntity(entity);
//            }
//            return doRequest(httpPost);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    };
    // Post请求带普通参数（优化编码）
    public static JSONObject executePost(String url, Map<String,String> parametersMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            if (parametersMap != null && !parametersMap.isEmpty()) {
                List<BasicNameValuePair> list = new ArrayList<>();
                for (Map.Entry<String, String> entry : parametersMap.entrySet()) {
                    list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
                // 显式指定UTF-8编码
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
                httpPost.setEntity(entity);
            }
            return doRequest(httpPost);
        } catch (Exception e) {
            throw new RuntimeException("POST请求（普通参数）执行失败", e);
        }
    };




    //Post请求带普通参数+带请求头
    public static JSONObject executePost(String url, Map<String,String> parmatersMap,Map<String,String> headMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }

        try {
            HttpPost httpPost = new HttpPost(url);
            //添加请求头
            addHeader(httpPost,headMap);
            //判断不为空
            if (parmatersMap != null && parmatersMap.size()>0){
                List<BasicNameValuePair> list = new ArrayList<>();
                //键值对关系
                Set<Map.Entry<String, String>> entries = parmatersMap.entrySet();
                for (Map.Entry<String, String> entry : entries) {
                    list.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list);
                httpPost.setEntity(entity);
            }
            return doRequest(httpPost);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    };



    //Post请求带文件上传的
//    public static JSONObject executePost(String url,Map<String,String> parmatersMap,String filename,String filePath){
//        try {
//            HttpPost httpPost = new HttpPost(url);
//            //form-data
//            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
//            //添加文件
//            builder.addBinaryBody(filename,new File(filePath));
//            //键值对关系
//            if (parmatersMap != null && parmatersMap.size()>0){
//                Set<Map.Entry<String, String>> entries = parmatersMap.entrySet();
//                for (Map.Entry<String, String> entry : entries) {
//                    //添加参数
//                    builder.addTextBody(entry.getKey(), entry.getValue());
//                }
//            }
//            //创建好请求实体
//            HttpEntity build = builder.build();
//            //设置好请求实体
//            httpPost.setEntity(build);
//            doRequest(httpPost);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return null;
//    }
    // 修复：Post请求带文件上传的
    public static JSONObject executePost(String url, Map<String,String> parmatersMap, String filename, String filePath){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();

            // 新增：校验文件是否存在（避免FileNotFoundException）
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在：" + filePath);
            }
            // 添加文件（原代码无问题，但建议指定ContentType）
            builder.addBinaryBody(filename, file, org.apache.http.entity.ContentType.DEFAULT_BINARY, file.getName());

            // 添加普通参数
            if (parmatersMap != null && !parmatersMap.isEmpty()) {
                for (Map.Entry<String, String> entry : parmatersMap.entrySet()) {
                    builder.addTextBody(entry.getKey(), entry.getValue());
                }
            }
            httpPost.setEntity(builder.build());
            // 接收并返回响应结果（原代码未返回）
            return doRequest(httpPost);
        } catch (Exception e) {
            throw new RuntimeException("POST请求（文件上传）执行失败", e);
        }
    }


    //Post请求带文件上传的+请求头
//    public static JSONObject executePost(String url,Map<String,String> parmatersMap,String filename,String filePath,Map<String,String> headMap){
//        try {
//            HttpPost httpPost = new HttpPost(url);
//            //添加请求头
//            addHeader(httpPost,headMap);
//            //form-data
//            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
//            //添加文件
//            builder.addBinaryBody(filename,new File(filePath));
//            //键值对关系
//            if (parmatersMap != null && parmatersMap.size()>0){
//                Set<Map.Entry<String, String>> entries = parmatersMap.entrySet();
//                for (Map.Entry<String, String> entry : entries) {
//                    //添加参数
//                    builder.addTextBody(entry.getKey(), entry.getValue());
//                }
//            }
//            //创建好请求实体
//            HttpEntity build = builder.build();
//            //设置好请求实体
//            httpPost.setEntity(build);
//            doRequest(httpPost);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return null;
//    }
    // 修复：Post请求带文件上传的+请求头（同理，补充返回值和文件校验）
    public static JSONObject executePost(String url, Map<String,String> parmatersMap, String filename, String filePath, Map<String,String> headMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            addHeader(httpPost, headMap);
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();

            // 校验文件
            File file = new File(filePath);
            if (!file.exists()) {
                throw new FileNotFoundException("文件不存在：" + filePath);
            }
            builder.addBinaryBody(filename, file, org.apache.http.entity.ContentType.DEFAULT_BINARY, file.getName());

            if (parmatersMap != null && !parmatersMap.isEmpty()) {
                for (Map.Entry<String, String> entry : parmatersMap.entrySet()) {
                    builder.addTextBody(entry.getKey(), entry.getValue());
                }
            }
            httpPost.setEntity(builder.build());
            // 接收并返回结果
            return doRequest(httpPost);
        } catch (Exception e) {
            throw new RuntimeException("POST请求（文件上传+请求头）执行失败", e);
        }
    }


    //Post请求json格式参数
    public static JSONObject executePost(String url,String json){


        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        if (json == null || json.trim().isEmpty()) {
            throw new IllegalArgumentException("JSON参数不能为空！");
        }
        try {
            HttpPost httpPost = new HttpPost(url);

            //设置请求头
            httpPost.setHeader("Content-Type","application/json;charset=UTF-8");

            //将请求实体设置给httppost对象
            StringEntity stringEntity = new StringEntity(json,"UTF-8");
            httpPost.setEntity(stringEntity);
            //执行post请求
            return doRequest(httpPost);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    //Post请求json格式参数+请求头
//    public static JSONObject executePost(String url,String json,Map<String,String> headMap){
//        try {
//            HttpPost httpPost = new HttpPost(url);
//            //添加请求头
//            addHeader(httpPost,headMap);
//            StringEntity stringEntity = new StringEntity(json);
//            //设置请求头
//            httpPost.setHeader("Content-Type","application/json;charset=UTF-8");
//            //将请求实体设置给httppost对象
//            httpPost.setEntity(stringEntity);
//            //执行post请求
//            doRequest(httpPost);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//        return null;
//    }
    // 修复：Post请求json格式参数+请求头（补充返回值）
    public static JSONObject executePost(String url, String json, Map<String,String> headMap){
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("请求URL不能为空！");
        }
        if (json == null || json.trim().isEmpty()) {
            throw new IllegalArgumentException("JSON参数不能为空！");
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            addHeader(httpPost, headMap);
            httpPost.setHeader("Content-Type","application/json;charset=UTF-8");
            System.out.println("这是穿惨过来的请求体："+json);
            StringEntity stringEntity = new StringEntity(json, "UTF-8"); // 显式指定编码
            httpPost.setEntity(stringEntity);
            // 接收并返回结果
            return doRequest(httpPost);
        } catch (Exception e) {
            throw new RuntimeException("POST请求（JSON+请求头）执行失败", e);
        }
    }


    //把添加请求头设置成一个方法
    public static void addHeader(HttpUriRequest request,Map<String,String>headMap){
        if (headMap != null && headMap.size()>0){
            Set<Map.Entry<String, String>> entries = headMap.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                //添加参数
               request.addHeader(entry.getKey(), entry.getValue());
            }
        }
    }




    /**
     * 请求并处理多种格式的响应
     * @return 处理结果（JSON对象或null）
     * @throws Exception 异常信息
     */
    public static JSONObject doRequest(HttpRequestBase request) throws Exception {

        try {
            // 打印请求基本信息
            String method = request.getMethod();
            String url = request.getURI().toString();
            System.out.println("执行" + method + "请求: " + url);

            // 执行请求获取响应
            HttpResponse response = httpclient.execute(request);
            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("响应状态码: " + statusCode);

            // 获取响应实体
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                System.out.println("响应内容为空");
                return null;
            }

            // 获取并打印响应内容类型
            String contentType = entity.getContentType() != null ?
                    entity.getContentType().getValue() : "未知类型";
            System.out.println("响应内容类型: " + contentType);

            // 读取响应内容
            String content = EntityUtils.toString(entity, "UTF-8");
            System.out.println("响应内容长度: " + content.length() + " 字符");

            // 根据状态码和内容类型处理响应
            if (statusCode == 200) {
                return handleSuccessResponse(contentType, content);
            } else {
                handleErrorResponse(statusCode, content);
                return null;
            }
        } finally {
            // 释放连接资源
            request.releaseConnection();
        }
    }

    /**
     * 处理成功响应（200状态码）
     */
    private static JSONObject handleSuccessResponse(String contentType, String content) {
        // 判断是否为JSON格式
        if (contentType.contains("application/json") ||
                (content.startsWith("{") && content.endsWith("}"))) {
            try {
                JSONObject jsonObject = new JSONObject(content);
                System.out.println("成功解析为JSON对象");
                System.out.println("JSON内容: " + jsonObject.toString(2)); // 格式化打印
                return jsonObject;
            } catch (Exception e) {
                System.out.println("内容声明为JSON但解析失败: " + e.getMessage());
                System.out.println("原始内容: " + content);
                return null;
            }
        }
        // 判断是否为HTML格式
        else if (contentType.contains("text/html") ||
                content.startsWith("<!DOCTYPE html>")) {
            System.out.println("响应为HTML格式");
            // 只打印前500个字符避免输出过长
            String displayContent = content.length() > 500 ?
                    content.substring(0, 500) + "..." : content;
            System.out.println("HTML内容: " + displayContent);
            return null;
        }
        // 其他文本格式
        else if (contentType.contains("text/")) {
            System.out.println("响应为文本格式");
            System.out.println("文本内容: " + content);
            return null;
        }
        // 二进制或其他无法直接显示的格式
        else {
            System.out.println("响应为二进制或非文本格式");
            System.out.println("无法直接显示，内容长度: " + content.length() + " 字符");
            return null;
        }
    }

    /**
     * 处理错误响应（非200状态码）
     */
    private static void handleErrorResponse(int statusCode, String content) {
        System.out.println("请求失败，状态码: " + statusCode);
        // 根据常见错误码给出提示
        if (statusCode == 404) {
            System.out.println("提示: 资源未找到，请检查URL是否正确");
        } else if (statusCode == 500) {
            System.out.println("提示: 服务器内部错误，请检查服务端日志");
        } else if (statusCode == 403) {
            System.out.println("提示: 没有访问权限");
        }
        System.out.println("错误响应内容: " + content);
    }

}






























